package packutil.event;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public abstract class AEventGenerator implements IEventGenerator {

	// event type to event listeners map
	private Map<Class<? extends IEvent>, List<IEventListener>> eventTypeListeners = new HashMap<Class<? extends IEvent>, List<IEventListener>>();

	// event id to event listeners map
	private Map<Integer, List<IEventListener>> eventIdListeners = new HashMap<Integer, List<IEventListener>>();

	/**
	 * Register event listener by event id
	 */
	public synchronized void addEventListener(IEventListener l, int eventId) {

		if (!eventIdListeners.containsKey(eventId)) {
			eventIdListeners.put(eventId, new ArrayList<IEventListener>());
		}

		eventIdListeners.get(eventId).add(l);
	}

	/**
	 * Register event listener by event type
	 */
	public synchronized void addEventListener(IEventListener l,
			Class<? extends IEvent> eventType) {

		if (!eventTypeListeners.containsKey(eventType)) {
			eventTypeListeners.put(eventType, new ArrayList<IEventListener>());
		}
		eventTypeListeners.get(eventType).add(l);
	}

	public synchronized void removeEventListener(IEventListener l,
			Class<? extends IEvent> eventType) {

		if (!eventTypeListeners.containsKey(eventType)) {
			return;
		}

		eventTypeListeners.get(eventType).remove(l);

		if (eventTypeListeners.get(eventType).isEmpty()) {
			eventTypeListeners.remove(eventType);
		}
	}

	public synchronized void removeEventListener(IEventListener l, int eventId) {

		if (!eventIdListeners.containsKey(eventId)) {
			return;
		}

		eventIdListeners.get(eventId).remove(l);

		if (eventIdListeners.get(eventId).isEmpty()) {
			eventIdListeners.remove(eventId);
		}

	}

	protected synchronized void throwEvent(IEvent e) {

		List<IEventListener> typeListeners = eventTypeListeners.get(e
				.getClass());

		if (typeListeners != null) {
			for (IEventListener l : typeListeners) {
				l.onEvent(e);
			}
		}

		List<IEventListener> idListeners = eventIdListeners.get(e.getEventId());

		if (idListeners != null) {
			for (IEventListener l : idListeners) {
				l.onEvent(e);
			}
		}
	}
}
